<?php
/**
 * 销售物料控制层
 *
 * @author kamisama.xia@gmail.com 
 * @version 0.1
 */

class material_ctl_admin_material_sales extends desktop_controller{

    var $workground = 'goods_manager';

    /**
     * 销售物料列表分栏菜单
     * 
     * @param Null
     * @return Array
     */
    function _views(){
        
        #不是销售列表时_隐藏Tab
        if($_GET['act'] != 'index')
        {
            return '';
        }
        
        $salesMaterialObj = app::get('material')->model('sales_material');

        $sub_menu = array(
            0 => array('label'=>app::get('base')->_('全部'),'optional'=>false),
            1 => array('label'=>app::get('base')->_('普通'),'filter'=>array('sales_material_type'=>1),'optional'=>false),
            2 => array('label'=>app::get('base')->_('促销'),'filter'=>array('sales_material_type'=>2),'optional'=>false),
            3 => array('label'=>app::get('base')->_('赠品'),'filter'=>array('sales_material_type'=>3),'optional'=>false),
        );

        foreach($sub_menu as $k=>$v){
            $sub_menu[$k]['filter'] = $v['filter']?$v['filter']:null;
            $sub_menu[$k]['addon'] = $salesMaterialObj->count($v['filter']);
            $sub_menu[$k]['href'] = 'index.php?app=material&ctl=admin_material_sales&act=index&view='.$k;
        }

        return $sub_menu;
    }

    /**
     * 销售物料列表项方法
     * 
     * @param Post
     * @return String
     */
    function index(){
        
        $params = array(
            'title'=>'销售物料',
            'actions' => array(
                    array(
                        'label' => '新建',
                        'href' => 'index.php?app=material&ctl=admin_material_sales&act=add',
                        'target' => '_blank',
                    ),
            ),
            'base_filter' => $base_filter,
            'use_buildin_set_tag'=>false,
            'use_buildin_recycle'=>false,
            'use_buildin_filter'=>true,
            'use_buildin_export'=>false,
        );

         $this->finder('material_mdl_sales_material',$params);
    }

    /**
     * @description 显示可售基础物料列表查询方法
     * @access public
     * @param void
     * @return void
     */
    function finder_common(){
        $params = array(
            'title'=>app::get('desktop')->_('基础物料列表'),
            'use_buildin_new_dialog' => false,
            'use_buildin_set_tag'=>false,
            'use_buildin_recycle'=>false,
            'use_buildin_export'=>false,
            'use_buildin_import'=>false,
            'use_buildin_filter'=>true,
            'use_buildin_setcol'=>true,
            'use_buildin_refresh'=>true,
            'finder_aliasname'=>'finder_common',
            'alertpage_finder'=>true,
            'use_buildin_tagedit'=>false,
        );

        $this->finder($_GET['app_id'].'_mdl_'.$_GET['object'],$params);
    }

    /**
     * @description 显示关联的物料
     * @access public
     * @param void
     * @return void
     */
    public function showMaterials()
    {
        $bm_id = kernel::single('base_component_request')->get_post('bm_id');

        if ($bm_id) {
            $this->pagedata['_input'] = array(
                'name' => 'bm_id',
                'idcol' => 'bm_id',
                '_textcol' => 'material_name',
            );

            $basicMaterialObj = app::get('material')->model('basic_material');
            $list = $basicMaterialObj->getList('bm_id,material_name, material_bn',array('bm_id'=>$bm_id),0,-1,'bm_id asc');
            
            //显示基础物料编码
            foreach ($list as $key => $val)
            {
                $list[$key]['material_name']    = $val['material_bn'] .' '. $val['material_name'];
            }
            
            $this->pagedata['_input']['items'] = $list;
        }

        $this->display('admin/material/sales/show_materials.html');
    }

    /**
     * 销售物料新增的展示页面方法
     * 
     * @param void
     * @return void
     */
    function add(){
        #过滤o2o门店店铺
        $shopObj = app::get('ome')->model('shop');
        $shopList = $shopObj->getList('shop_id,name', array('s_type'=>1), 0, -1);
        array_unshift($shopList,array('shop_id'=>'_ALL_','name'=>'全部店铺'));
        $this->pagedata['shops'] = $shopList;
        $this->singlepage('admin/material/sales/add.html');
    }

    /**
     * 基础物料新增提交方法
     * 
     * @param Post
     * @return Boolean
     */
    function toAdd(){
        $this->begin('index.php?app=material&ctl=admin_material_sales&act=index');

        if(!$this->checkAddParams($_POST, $err_msg)){
            $this->end(false, $err_msg);
        }

        $salesMaterialObj = app::get('material')->model('sales_material');
        $salesMaterialExtObj = app::get('material')->model('sales_material_ext');
        $salesMaterialShopFreezeObj = app::get('material')->model('sales_material_shop_freeze');

        //保存物料主表信息
        $addData = array(
            'sales_material_name' => $_POST['sales_material_name'],
            'sales_material_bn' => $_POST['sales_material_bn'],
            'sales_material_bn_crc32' => $_POST['sales_material_bn_crc32'],
            'sales_material_type' => $_POST['sales_material_type'],
            'shop_id' => $_POST['shop_id'],
            'create_time' => time(),
        );
        $is_save = $salesMaterialObj->save($addData);

        if($is_save){
            $is_bind = false;
            //如果有关联物料就做绑定操作
            $salesBasicMaterialObj = app::get('material')->model('sales_basic_material');
            //普通销售物料关联
            if(($_POST['sales_material_type'] == 1 || $_POST['sales_material_type'] == 3) && !empty($_POST['bm_id'])){
                $addBindData = array(
                        'sm_id' => $addData['sm_id'],
                        'bm_id' => $_POST['bm_id'],
                        'number' => 1,
                );
                $salesBasicMaterialObj->insert($addBindData);

                $is_bind = true;
            }elseif($_POST['sales_material_type'] == 2 && !empty($_POST['at'])){
            //促销销售物料关联
                foreach($_POST['at'] as $k=>$v){
                    $addBindData = array(
                        'sm_id' => $addData['sm_id'],
                        'bm_id' => $k,
                        'number' => $v,
                        'rate' => $_POST['pr'][$k],
                    );
                    $salesBasicMaterialObj->insert($addBindData);
                    $addBindData = null;
                }

                $is_bind = true;
            }

            //如果有绑定物料数据，设定销售物料为绑定状态
            if($is_bind){
                $salesMaterialObj->update(array('is_bind'=>1),array('sm_id'=>$addData['sm_id']));
            }

            //保存销售物料扩展信息
            $addExtData = array(
                'sm_id' => $addData['sm_id'],
                'cost' => $_POST['cost'] ? $_POST['cost'] : 0.00,
                'retail_price' => $_POST['retail_price'] ? $_POST['retail_price'] : 0.00,
                'weight' => $_POST['weight'] ? $_POST['weight'] : 0.00,
                'unit' => $_POST['unit'],
            );
            $salesMaterialExtObj->insert($addExtData);
            
            //保存销售物料店铺级冻结
            if($_POST['shop_id'] != '_ALL_'){
                $addStockData = array(
                    'sm_id' => $addData['sm_id'],
                    'shop_id' => $_POST['shop_id'],
                    'shop_freeze' => 0,
                );
                $salesMaterialShopFreezeObj->insert($addStockData);
            }

            $this->end(true, '操作成功');
        }else{
            $this->end(false, '保存失败');
        }

    }

    /**
     * 销售物料新增时的参数检查方法
     * 
     * @param Array $params 
     * @param String $err_msg
     * @return Boolean
     */
    function checkAddParams(&$params, &$err_msg){
        if(empty($params['sales_material_name']) || empty($params['sales_material_bn'])){
            $err_msg ="必填信息不能为空";
            return false;
        }
        
        //判断物料编码只能是由数字英文下划线组成
        $reg_bn_code = "/^[0-9a-zA-Z\_]*$/";
        if(!preg_match($reg_bn_code,$params["sales_material_bn"])){
            $err_msg = "物料编码只能是数字英文下划线组成";
            return false;
        }

        $salesMaterialObj = app::get('material')->model('sales_material');
        $salesMaterialInfo = $salesMaterialObj->getList('sales_material_bn',array('sales_material_bn'=>$params['sales_material_bn']));
        if($salesMaterialInfo){
            $err_msg ="当前新增的物料编码已被使用，不能重复";
            return false;
        }

        $params['sales_material_bn_crc32'] = sprintf('%u',crc32($params['sales_material_bn']));

        if($params['sales_material_type'] == 2){
            if(!isset($params['at'])){
                $err_msg ="促销物料请至少设置一个物料明细内容";
                return false;
            }

            foreach ($params['at'] as $val){
                if (count($params['at']) == 1){
                    if ($val <2){
                        $err_msg ="只有一种物料时，数量必须大于1";
                        return false;
                    }
                }else {
                    if ($val < 1){
                        $err_msg ="数量必须大于0";
                        return false;
                    }
                }
            }

            foreach ($params['pr'] as $val){
                $tmp_rate +=$val;
            }

            if($tmp_rate > 100){
                $err_msg ="分摊销售价合计百分比:".$tmp_rate.",已超100%";
                return false;
            }elseif($tmp_rate < 100){
                $err_msg ="分摊销售价合计百分比:".$tmp_rate.",不足100%";
                return false;
            }
        }
        return true;
    }

    /**
     * 销售物料编辑的展示页面方法
     * 
     * @param Int $bm_id
     * @return Boolean
     */
    function edit($sm_id){
        $this->begin('index.php?app=material&ctl=admin_material_sales&act=index');
        if (empty($sm_id)){
            $this->end(false,'操作出错，请重新操作');
        }

        $salesMaterialObj = app::get('material')->model('sales_material');
        
        $tmp_sm_id = intval($sm_id);
        $salesMaterialInfo = $salesMaterialObj->dump($tmp_sm_id);
        if(!$salesMaterialInfo){
            $this->end(false,'操作出错，请重新操作');
        }

        //检查物料是否有关联的订单,关联的基础物料不能改变
        //todo 需实现 readonly
        $readonly = $this->checkEditReadOnly($salesMaterialInfo['shop_id'], $tmp_sm_id, $salesMaterialInfo['is_bind']);

        //读取合并销售物料的扩展信息
        $salesMaterialExtObj = app::get('material')->model('sales_material_ext');
        $salesMaterialExtInfo = $salesMaterialExtObj->dump($tmp_sm_id);
        $salesMaterialInfo = array_merge($salesMaterialInfo,$salesMaterialExtInfo);
        
        if(($salesMaterialInfo['sales_material_type'] == 1 || $salesMaterialInfo['sales_material_type'] == 3) && $salesMaterialInfo['is_bind'] == 1){
            $salesBasicMaterialObj = app::get('material')->model('sales_basic_material');
            $salesBasicMaterialInfo = $salesBasicMaterialObj->dump(array('sm_id'=>$tmp_sm_id));
            $count = count($salesBasicMaterialInfo['bm_id']);
            $this->pagedata['bind_bm_id'] = $salesBasicMaterialInfo['bm_id'];
            $this->pagedata['replacehtml'] = <<<EOF
<div id='hand-selected-product'>已选择了{$count}个物料,<a href='javascript:void(0);' onclick='material_selected_show();'>查看关联的物料.</a></div>
EOF;
        }

        //店铺信息(过滤o2o门店店铺)
        $shopObj = app::get('ome')->model('shop');
        $shopList = $shopObj->getList('shop_id,name', array('s_type'=>1), 0, -1);
        array_unshift($shopList,array('shop_id'=>'_ALL_','name'=>'全部店铺'));
        $this->pagedata['shops'] = $shopList;

        $this->pagedata['material_info'] = $salesMaterialInfo;
        $this->pagedata['readonly'] = $readonly;
        $this->singlepage('admin/material/sales/edit.html');
    }

    /**
     * 检查基础物料个别参数是否可编辑
     * 
     * @param Int $bm_id
     * @return Array
     */
    function checkEditReadOnly($shop_id, $sm_id, $is_bind){
        $readonly = array('type' => false,'shop'=>false,'bind_item'=>false);

        //如果销售物料有冻结、订单，那么物料类型不能变
        if($shop_id != '_ALL_'){
            $shopFreezeObj = app::get('material')->model('sales_material_shop_freeze');
            $storeInfo = $shopFreezeObj->getList('shop_freeze',array('sm_id'=>$sm_id,'shop_id'=>$shop_id));
            if($storeInfo[0]['shop_freeze'] > 0){
                $is_type_readonly = true;
            }
        }

        $orderObjObj = app::get('ome')->model('order_objects');
        $orderInfo = $orderObjObj->getList('obj_id,goods_id',array('goods_id'=>$sm_id));
        if($orderInfo){
            $has_object = true;
            $is_type_readonly = true;
            $is_shop_readonly = true;
        }

        if($is_type_readonly){
            $readonly['type'] = true;
        }

        if($is_shop_readonly){
            $readonly['shop'] = true;
        }

        //已绑定有订单的不能变
        if($is_bind == 1 && $has_object == true){
            $orderItemObj = app::get('ome')->model('order_items');
            $orderItemInfo = $orderItemObj->db->select("select item_id from sdb_ome_order_items as oi left join sdb_ome_order_objects as oo on oi.obj_id = oo.obj_id where goods_id = ".$sm_id." LIMIT 0,1");
            if($orderItemInfo){
                $is_bind_item_readonly = true;
            }
        }

        if($is_bind_item_readonly){
            $readonly['bind_item'] = true;
        }

        return $readonly;
    }

    /**
     * 销售物料编辑提交方法
     * 
     * @param Int $sm_id
     * @return Boolean
     */
    function toEdit(){
        $this->begin('index.php?app=material&ctl=admin_material_sales&act=index');

        if(!$this->checkEditParams($_POST, $err_msg)){
            $this->end(false, $err_msg);
        }

        $salesMaterialObj = app::get('material')->model('sales_material');
        $salesMaterialExtObj = app::get('material')->model('sales_material_ext');

        //更新基础物料基本信息
        $updateData['sales_material_name'] = $_POST['sales_material_name'];
        $updateData['sales_material_type'] = $_POST['sales_material_type'];
        $updateData['shop_id'] = $_POST['shop_id'];
        $filter['sm_id'] = $_POST['sm_id'];

        $is_update = $salesMaterialObj->update($updateData,$filter);
        if($is_update){
            $is_bind = false;
            //如果有关联物料就做绑定操作
            $salesBasicMaterialObj = app::get('material')->model('sales_basic_material');
            //删除原有关联基础物料信息
            $salesBasicMaterialObj->delete(array('sm_id'=>$filter['sm_id']));

            //普通销售物料关联
            if(($_POST['sales_material_type'] == 1 || $_POST['sales_material_type'] == 3) && !empty($_POST['bm_id'])){
                $addBindData = array(
                        'sm_id' => $filter['sm_id'],
                        'bm_id' => $_POST['bm_id'],
                        'number' => 1,
                );
                $salesBasicMaterialObj->insert($addBindData);

                $is_bind = true;
            }elseif($_POST['sales_material_type'] == 2 && !empty($_POST['at'])){
            //促销销售物料关联
                foreach($_POST['at'] as $k=>$v){
                    $addBindData = array(
                        'sm_id' => $filter['sm_id'],
                        'bm_id' => $k,
                        'number' => $v,
                        'rate' => $_POST['pr'][$k],
                    );
                    $salesBasicMaterialObj->insert($addBindData);
                    $addBindData = null;
                }

                $is_bind = true;
            }

            //如果有绑定物料数据，设定销售物料为绑定状态
            if($is_bind){
                $salesMaterialObj->update(array('is_bind'=>1),array('sm_id'=>$filter['sm_id']));
            }else{
                $salesMaterialObj->update(array('is_bind'=>2),array('sm_id'=>$filter['sm_id']));
            }

            //更新销售物料扩展信息
            $updateExtData = array(
                'cost' => $_POST['cost'] ? $_POST['cost'] : 0.00,
                'retail_price' => $_POST['retail_price'] ? $_POST['retail_price'] : 0.00,
                'weight' => $_POST['weight'] ? $_POST['weight'] : 0.00,
                'unit' => $_POST['unit'],
            );
            $salesMaterialExtObj->update($updateExtData, $filter);

            $this->end(true, '保存成功');
        }else{
            $this->end(false, '保存失败');
        }

    }

    /**
     * 销售物料编辑时的参数检查方法
     * 
     * @param Array $params 
     * @param String $err_msg
     * @return Boolean
     */
    function checkEditParams(&$params, &$err_msg){

        if(empty($params['sales_material_name']) || empty($params['sales_material_bn']) || empty($params['sm_id'])){
            $err_msg ="必填信息不能为空";
            return false;
        }

        $salesMaterialObj = app::get('material')->model('sales_material');
        $salesMaterialExistInfo = $salesMaterialObj->getList('sm_id',array('sales_material_bn'=>$params['sales_material_bn']));
        if($salesMaterialExistInfo && $salesMaterialExistInfo[0]['sm_id'] != $params['sm_id']){
            $err_msg ="当前编辑的物料编码已被使用，不能重复";
            return false;
        }

        $salesMaterialInfo = $salesMaterialObj->dump($params['sm_id']);
        if(!$salesMaterialInfo){
            $err_msg ="当前物料不存在";
            return false;
        }

        if($params['sales_material_type'] == 2){
            if(!isset($params['at'])){
                $err_msg ="组合物料请至少设置一个物料明细内容";
                return false;
            }

            foreach ($params['at'] as $val){
                if (count($params['at']) == 1){
                    if ($val <2){
                        $err_msg ="只有一种物料时，数量必须大于1";
                        return false;
                    }
                }else {
                    if ($val < 1){
                        $err_msg ="数量必须大于0";
                        return false;
                    }
                }
            }

            foreach ($params['pr'] as $val){
                $tmp_rate +=$val;
            }

            if($tmp_rate > 100){
                $err_msg ="分摊销售价合计百分比:".$tmp_rate.",已超100%";
                return false;
            }elseif($tmp_rate < 100){
                $err_msg ="分摊销售价合计百分比:".$tmp_rate.",不足100%";
                return false;
            }
        }

        return true;
    }

    /**
     * 促销类销售物料关联的基础物料信息异步加载方法
     * 
     * @param Int $sm_id
     * @return String
     */
    function getEditMaterial($sm_id){
        if ($sm_id == ''){
            $sm_id = $_POST['p[0]'];
        }
        
        $salesBasicMaterialObj = app::get('material')->model('sales_basic_material');
        $basicMaterialObj = app::get('material')->model('basic_material');

        $rows = array();
        $items = $salesBasicMaterialObj->getList('bm_id,sm_id,number,rate',array('sm_id'=>$sm_id),0,-1);
        foreach($items as $k => $item){
            $basicMaterialInfo = $basicMaterialObj->dump(array('bm_id'=>$item['bm_id']),'material_bn,material_name');
            $items[$k] = array_merge($item,$basicMaterialInfo);
        }

        echo json_encode($items);
    }

    /**
     * 销售物料列表弹窗数据获取方法
     * 
     * @param Void
     * @return String
     */
    function findSalesMaterial(){
        //已绑定的销售物料才可选择
        $base_filter = array('is_bind'=>1);

        if($_GET['shop_id']){
            $shop = explode('*',$_GET['shop_id']);
            $base_filter['shop_id'] = array($shop[0], '_ALL_');
        }

        if($_GET['type']){
            $base_filter['sales_material_type'] = $_GET['type'];
        }

        $params = array(
            'title'=>'销售物料列表',
            'use_buildin_new_dialog' => false,
            'use_buildin_set_tag'=>false,
            'use_buildin_recycle'=>false,
            'use_buildin_export'=>false,
            'use_buildin_import'=>false,
            'use_buildin_filter'=>true,
            'base_filter' => $base_filter,
        );
        $this->finder('material_mdl_sales_material', $params);
    }

    /**
     * 销售物料列表弹窗选中物料信息查询方法
     * 
     * @param Int $bm_id
     * @return String
     */
    function getSalesMaterial(){
        $sm_id = $_POST['sm_id'];
        $sales_material_bn= $_GET['sales_material_bn'];
        $sales_material_name= $_GET['sales_material_name'];
        
        if (is_array($sm_id)){
            if ($sm_id[0] == "_ALL_"){
                $filter = '';
            }else {
                $filter['sm_id'] = $sm_id;
            }
        }
        
        if($sales_material_bn){
           $filter = array(
               'sales_material_bn'=>$sales_material_bn
           );
        }
        
        if($sales_material_name){
            $filter = array(
               'sales_material_name'=>$sales_material_name
           );
        }

        $salesMaterialObj = app::get('material')->model('sales_material');
        $salesMaterialExtObj = app::get('material')->model('sales_material_ext');
        $salesMStockLib = kernel::single('material_sales_material_stock');
        $salesBasicMaterialObj = app::get('material')->model('sales_basic_material');
        $basicMaterialObj = app::get('material')->model('basic_material');

        $filter['use_like'] = 1;
        $data = $salesMaterialObj->getList('sm_id,sales_material_name,sales_material_bn',$filter,0,-1);

        if (!empty($data)){
            foreach ($data as $k => $item){
                $store = $salesMStockLib->getSalesMStockById($item['sm_id']);
                $ExtInfo = $salesMaterialExtObj->dump($item['sm_id'],'retail_price');
                $promoItems = $salesBasicMaterialObj->getList('*',array('sm_id'=>$item['sm_id']),0,-1);
                if($promoItems){
                    foreach($promoItems as $pk => &$promoItem){
                        $tmp_item = $basicMaterialObj->getList('material_name,material_bn',array('bm_id'=>$promoItem['bm_id']),0,1);
                        $promoItem = array_merge($promoItem , $tmp_item[0]);
                    }
                    $item['items'] = $promoItems;
                }

                $item['store'] = $store;
                $item['num'] = 1;
                $item['price'] = $ExtInfo['retail_price'];
                $rows[] = $item;
            }
        }
        echo json_encode($rows);
    }

}
